/*
 * Base types for CACT.
 */

#ifndef __CACT_TYPE_H__
#define __CACT_TYPE_H__

#include <vector>
#include <cstdint>

/* Base types in CACT */
enum class Btype {UNKNOWN = 0, VOID, INT, BOOL, FLOAT, DOUBLE};

/*
 * Type for var def, expr, ...
 * For example, { {5, 0}, {3, 3}, {0, 5} } has type:
 * true, Btype::INT, {3, 2}.
 */
struct cact_type_t {
	bool is_const;
	Btype base_type;
	// `dim.size()` is the number of dimensions
	std::vector<uint32_t> dim;
};

struct number_type_t {
	union {
		int64_t ival;
		double dval;
		float fval;
	};
	Btype type;	// Only `INT`, `FLOAT` and `DOUBLE` are valid
};

// Get size (byte) of a base type, must be power of 2!
static inline uint32_t cactsize(Btype type)
{
	switch (type)
	{
	case Btype::INT:
		return 4u;
		break;
	case Btype::FLOAT:
		return 4u;
		break;
	case Btype::DOUBLE:
		return 8u;
		break;
	case Btype::BOOL:
		return 1u;
		break;
	default:
		return 0u;
		break;
	}
}

// Rounding: make sure that `unit` is power of 2!
static inline uint64_t roundup(uint64_t size, uint64_t unit)
{
	return (size + unit - 1ul) & ~(unit - 1u);
}
static inline uint64_t rounddown(uint64_t addr, uint64_t unit)
{
	return (addr) & ~(unit - 1u);
}

#endif